package com.example.match.camera;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.widget.TextView;


import com.example.match.mui.BlankPageActivity;
import com.example.match.mui.MainUIActivity;
import com.example.mylibrary.MyApp;
import com.example.mylibrary.config.Config;
import com.example.mylibrary.data.ByteImg;
import com.example.mylibrary.data.StudentInfo;
import com.example.mylibrary.util.EventUtil;
import com.example.mylibrary.util.ImageUtil;
import com.example.mylibrary.util.Logger;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import cn.com.aratek.facelib.AraFaceAuthLib;




/**
 * Created by Administrator on 2018/1/24.
 */

public class CameraInterface implements  Camera.PreviewCallback {
    private static final int MSG_SHOW_PROGRESS_DIALOG = 3;
    private static final int MSG_DISMISS_PROGRESS_DIALOG = 4;
    private Camera mCamera;
    private Camera.Parameters mParams;
    private boolean isPreviewing = false;
    private static CameraInterface mCameraInterface;
    static Activity mActivity;
    private static Context mContext;
    private static FacePicInterface inter;
    private static MyApp app;
    private Logger logger = new Logger();
    private static int mCount;
    private static ExecutorService cachedThreadPool;
    private static ExecutorService fixThreadPool;
    private ProgressDialog progressDialog;
  //  private TransitionActivity transition;
    private boolean faceDetectFinish = true;
    private FaceDetectThread detectThread;
    private FaceView faceView;
    private FragmentCamera fragment;
    private int mCameraId;
    private static AraFaceAuthLib araFaceAuthLib;
    private StudentInfo studentInfo;
    private List<StudentInfo> studentInfoAll;
    private byte[] cardData = null;
    private ArrayList<ByteImg> bytes;
    private static float faceScore;
  //  private ItemGropActivity itemGropActivity;
    private BlankPageActivity blankPageActivity;

    private CameraInterface(){
    }
    public static void setVerifyCount(int count) {
        mCount = count;
    }


    public static synchronized CameraInterface getInstance(Context context) {
        mContext = context;
        mActivity = (Activity) context;
        inter = (FacePicInterface) mActivity;
        if (mCameraInterface == null) {
            mCameraInterface = new CameraInterface();
        }
        app = MyApp.getInstance();
        cachedThreadPool = Executors.newCachedThreadPool();
        fixThreadPool = Executors.newFixedThreadPool(2);


        SharedPreferences sp =   context.getSharedPreferences("data",0);
        faceScore = sp.getFloat("faceScore",0);
        Log.e( "faceScore----->: ",faceScore+"" );

        return mCameraInterface;
    }
    public void doOpenCamera(SurfaceHolder holder, int cameraId) {
        mCamera = Camera.open(cameraId);
        mCameraId = cameraId;

    }
    public void doOpenFlash() {
        try {
            mParams = mCamera.getParameters();
            mParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
            mCamera.setParameters(mParams);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void doCloseFlash() {
        try {
            mParams = mCamera.getParameters();
            mParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
            mCamera.setParameters(mParams);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void doStartPreview(SurfaceHolder holder,float previewRate){


           blankPageActivity = (BlankPageActivity) mContext;
            fragment = blankPageActivity.getFragment();







        faceView = fragment.getFaceView();
        if (isPreviewing) {
            mCamera.stopPreview();
            return;
        }

        if (mCamera != null) {
            mParams = mCamera.getParameters();
            mParams.setPictureFormat(PixelFormat.JPEG);
            mParams.setPreviewSize(Config.WIDTH, Config.HEIGHT);
            mParams.setPictureSize(Config.WIDTH, Config.HEIGHT);
            mParams.setPreviewFrameRate(15);
            mParams.setJpegQuality(95);
            setCameraDisplayOrientation();
            List<String> focusModes = mParams.getSupportedFocusModes();
            if (focusModes.contains("continuous-video")) {
                mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
            }
            mCamera.setParameters(mParams);
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.setPreviewCallback(this);
                mCamera.startPreview();
            } catch (IOException e) {
                e.printStackTrace();
            }
            isPreviewing = true;
            mParams = mCamera.getParameters();
        }
    }
    //摄像头旋转
    private void setCameraDisplayOrientation() {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(mCameraId, info);
        int rotation = mActivity.getWindowManager().getDefaultDisplay()
                .getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360; // compensate the mirror
        } else { // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        mCamera.setDisplayOrientation(result);
    }


    public void startPreview() {
        mCamera.startPreview();
    }

    public void stopPreview() {
        mCamera.stopPreview();
    }

    /**
     * stop preview Camera
     */
    public void doStopCamera() {
        if (null != mCamera) {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            isPreviewing = false;
            mCamera.release();
            mCamera = null;
        }

    }

    public void doTakePicture() {
        try {
            if (isPreviewing && (mCamera != null)) {
                mCamera.takePicture(mShutterCallback, null,
                        mJpegPictureCallback);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public Camera.Parameters getCameraParams() {
        if (mCamera != null) {
            mParams = mCamera.getParameters();
            return mParams;
        }
        return null;
    }

    public Camera getCameraDevice() {
        return mCamera;
    }

    public FragmentCamera getFragment() {
        return fragment;
    }

    public AraFaceAuthLib getAraFaceAuthLib() {
        return araFaceAuthLib;
    }


    ShutterCallback mShutterCallback = new ShutterCallback() {
    public void onShutter() {
    }
};
    PictureCallback mJpegPictureCallback = new PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
        stopPreview();
        isPreviewing = false;
        progressDialog = new ProgressDialog(fragment.getActivity());
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progressDialog.setIcon(android.R.drawable.ic_dialog_info);
        progressDialog.setIndeterminate(false);
        progressDialog.setCancelable(false);
        progressDialog.setMessage("正在比对，请稍候...");
        progressDialog.setTitle("正在加载");
        progressDialog.show();
        final byte[] snapshotFeature = data;
        cachedThreadPool = Executors.newCachedThreadPool();
        cachedThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                OffLineVerification(snapshotFeature);
            }
        });
    }

};


        //离线人脸比对
    private void OffLineVerification(byte[] data) {
        bytes = new ArrayList<ByteImg>();
        araFaceAuthLib = MainUIActivity.getAraFaceAuthLib();
        Bitmap bmp2 = BitmapFactory.decodeByteArray(data, 0, data.length);
        Bitmap b = ImageUtil.getRotateBitmap(bmp2, Config.displayOrientation);
        byte[] SnapshotData = araFaceAuthLib.getFeature(b);
        bytes = fragment.getBytes();
        float score ;
        String stuCode;

        for (int i = 0; i< bytes.size(); i++){
            score = araFaceAuthLib.verify(bytes.get(i).getByteImg(), SnapshotData);
            if(score>85) {
                stuCode = bytes.get(i).getStudentCode();
                handler.sendEmptyMessage(MSG_DISMISS_PROGRESS_DIALOG);
                Bundle bundle = new Bundle();
                bundle.putFloat("score", score);
                bundle.putByteArray("snapshotFeature", data);
                bundle.putString("stuCode",stuCode);
                Log.e( "stuCodeA: ------>",stuCode );
                handler.sendMessage(handler.obtainMessage(
                        EventUtil.MSG_FACEVERIFY_RESULT, bundle));
                BackToCollection(score, data,stuCode);
//
                break;

            }else {

                if(i==bytes.size()-1){
                    handler.sendEmptyMessage(MSG_DISMISS_PROGRESS_DIALOG);
                    Bundle bundle = new Bundle();
                    bundle.putFloat("score", score);
                    bundle.putByteArray("snapshotFeature", data);
                    handler.sendMessage(handler.obtainMessage(
                            EventUtil.MSG_FACEVERIFY_RESULT, bundle));
                }
            }

        }


    }


    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case EventUtil.MSG_FACEVERIFY_RESULT: {
                    Bundle bundle = (Bundle) msg.obj;
                    float score = bundle.getFloat("score");
                    logger.e("score = " + score);
                    if (score == 0 || score == -1) {
                        if (mCount == 1) {
                            BackToCollection(score,
                                    bundle.getByteArray("snapshotFeature"),  bundle.getString("stuCode"));
                        } else {
                            mCount--;
                            String str;
                            if (score == 0) {
                                str = "比对失败";
                            } else {
                                str = "未检测到人脸";
                            }
                            showResultMessage(str);
                        }
                    } else {
                        BackToCollection(score,
                                bundle.getByteArray("snapshotFeature"),  bundle.getString("stuCode"));
                    }
                    break;
                }
                case EventUtil.UPDATE_FACE_RECT: {
                    final FaceResult faceResult = (FaceResult) msg.obj;
                    if (app.getPreferences().getInt(Config.KEY_SHUTTER_MODE,
                            Config.MODE_AUTO) == Config.MODE_AUTO) {
                        faceView.setFaces(faceResult);
                        faceDetectFinish = true;
                        app.faceDetectRectShowCount++;
                        faceDetectFinish = true;
                        if (app.faceDetectRectShowCount >= 5) {
                            app.faceDetectRectShowCount = 0;
                            doTakePicture();
                        }

                    } else {
                        break;
                    }
                    break;
                }
                case EventUtil.UPDATE_NO_FACE_RECT: {
                    faceView.clearFaces();
                    app.faceDetectRectShowCount = 0;
                    faceDetectFinish = true;
                    break;
                }
                case MSG_SHOW_PROGRESS_DIALOG: {
                    progressDialog.setMessage("正在比对，请稍候...");
                    progressDialog.setTitle("正在加载");
                    progressDialog.show();
                    break;
                }
                case MSG_DISMISS_PROGRESS_DIALOG: {
                    progressDialog.dismiss();
                    break;
                }
                default:
                    break;



            }
        };

    };


    private void BackToCollection(float score, byte[] snapshotFeature,String stuCode) {

       Intent intent1 = new Intent();
        intent1.putExtra("score", score);
        intent1.putExtra("snapshotFeature", snapshotFeature);
        intent1.putExtra("stuCode", stuCode);
        Log.e( "stuCodeB: ------>",stuCode );
        logger.e("snapshotFeature = " + snapshotFeature);
        fixThreadPool.shutdownNow();
        inter.fromPic(222, 1, intent1);
        blankPageActivity.getFragmentManager().popBackStack();

    }
    /**
     * 弹出对话框并显示提示
     *
     * @param str
     */
    private void showResultMessage(String str) {
        faceDetectFinish = false;
        faceView.clearFaces();
        TextView tv = new TextView(mActivity);
        tv.setText(str);
        tv.setTextSize(20);
        tv.setPadding(5, 2, 5, 2);
        tv.setGravity(Gravity.CENTER);
        tv.setTextColor(Color.rgb(255, 165, 0));
        AlertDialog.Builder dialog = new AlertDialog.Builder(mActivity);
        dialog.setTitle("提示").setView(tv).setCancelable(false)
                .setPositiveButton("重拍", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                        startPreview();
                        isPreviewing = true;
                        mCamera.setPreviewCallback(CameraInterface.this);
                        faceDetectFinish = true;
                    }
                }).create().show();
    }
    /**
     * 开始人脸识别
     */
    private void startFaceDetect(byte[] data) {
        faceDetectFinish = false;
        detectThread = new FaceDetectThread(mContext, handler, data);
        detectThread.start();
    }


    /**
     * 停止人脸识别
     */
    private void stopFaceDetect() {
        detectThread = null;
        faceView.clearFaces();
        faceDetectFinish = true;
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        if (app.getPreferences().getInt(Config.KEY_SHUTTER_MODE,
                Config.MODE_AUTO) == Config.MODE_AUTO) {
            if (faceDetectFinish) {
                startFaceDetect(data);
            }
        } else {
            stopFaceDetect();
        }
    }

}
